// Gramatyka drzewiasta - z niej zostanie zbudowany parser, ktory bedzie przeprowadzal konkretne obliczenia

tree grammar FOLStage3;

options
{
	tokenVocab=FOLStage2;
	ASTLabelType=CommonTree;
	output=AST;
}

@header
{
package org.protege.owl.examples.tab.grammar;
}

@members
{
	boolean quantifierNeg = false;
}

// Przerobic na liste kwantyfikatorow, w skrajnym przypadku pusta!
stat:
	^(STAT qtflist expr[quantifierNeg])
	;
	
qtflist:
	^(QTF qtf*)
	;

qtf:
	^(NEG {quantifierNeg = !quantifierNeg;} qtfpart)
	-> qtfpart
	|
	qtfpart
	;
	
qtfpart:
	forall
	|
	exists
	;

forall:
	^(FORALL rng)
	-> {quantifierNeg}? ^(EXISTS rng)
	-> ^(FORALL rng)
	;

exists:
	^(EXISTS rng)
	-> {quantifierNeg}? ^(FORALL rng)
	-> ^(EXISTS rng)
	;

rng:
	varlist ^(EXPR expr[false])
	;

varlist:
	^(VAR ID+)
	;

expr[boolean neg]
	:
	or[$neg]
	|
	and[$neg]
	|
	not[$neg]
	|
	quark[$neg]
	;
	
or[boolean neg]
	:
	^(OR expr[$neg] expr[$neg])
	-> {$neg}? ^(AND expr expr)
	-> ^(OR expr expr);
	
and[boolean neg]
	:
	^(AND expr[$neg] expr[$neg])
	-> {$neg}? ^(OR expr expr)
	-> ^(AND expr expr)
	;

not[boolean neg]
	:
	^(NOT expr[!$neg])
	-> expr
	;

quark[boolean neg]
	:
	predcall
	-> {$neg}? ^(NOT predcall)
	-> predcall
	;

predcall:
	^(IS ID arg)
	|
	^(REL ID arg arg)
	;

arg:
	ID
	;
	
